import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs';
import { NGX_MONACO_EDITOR_CONFIG, NgxMonacoEditorConfig } from './config';


let loadPromise: Promise<void>;

@Component({
  template: ''
})
export abstract class BaseEditor implements AfterViewInit, OnDestroy, OnInit {
  @ViewChild('editorContainer', { static: true }) _editorContainer: ElementRef;
  @Output() onInit = new EventEmitter<any>();
  protected _editor: any;
  protected _options: any;
  protected _windowResizeSubscription: Subscription;

  constructor(@Inject(NGX_MONACO_EDITOR_CONFIG) protected config: NgxMonacoEditorConfig) { }



  ngOnInit() {

  }

  ngAfterViewInit(): void {
    loadPromise = new Promise<void>((resolve: any) => {
      const baseUrl = (this.config.baseUrl || './assets') + '/monaco-editor/min/vs';
      if (typeof ((<any>window).monaco) === 'object') {
        resolve();
        return;
      }
      const onGotAmdLoader: any = () => {
        // Load monaco
        (<any>window).require.config({ paths: { 'vs': `${baseUrl}` } });
        (<any>window).require([`vs/editor/editor.main`], () => {
          if (typeof this.config.onMonacoLoad === 'function') {
            this.config.onMonacoLoad();
          }
          this.initMonaco(this._options);
          resolve();
        });
      };

      // Load AMD loader if necessary
      if (!(<any>window).require) {
        const loaderScript: HTMLScriptElement = document.createElement('script');
        loaderScript.type = 'text/javascript';
        loaderScript.src = `${baseUrl}/loader.js`;
        loaderScript.addEventListener('load', onGotAmdLoader);
        document.body.appendChild(loaderScript);
      } else {
        onGotAmdLoader();
      }
    });

     // Wait until monaco editor is available
    loadPromise.then(() => {
      this.initMonaco(this._options);
      
    });
  }


  protected abstract initMonaco(options: any): void;

  ngOnDestroy() {
    if (this._windowResizeSubscription) {
      this._windowResizeSubscription.unsubscribe();
    }
    if (this._editor) {
      this._editor.dispose();
      this._editor = undefined;
    }
  }
}
